package com.wx.spider.pc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wx.spider.common.enums.MqMsgBean;
import com.wx.spider.common.model.CommonResponse;
import com.wx.spider.common.model.Constants;
import com.wx.spider.common.model.mq.GetListMessage;
import com.wx.spider.common.pojo.db.WxBiz;
import com.wx.spider.common.pojo.db.WxBizNews;
import com.wx.spider.common.pojo.db.WxBizSpider;
import com.wx.spider.common.pojo.mongo.WxNewsListJson;
import com.wx.spider.common.util.HttpClientUtil;
import com.wx.spider.common.util.IdGenerateUtil;
import com.wx.spider.common.util.JsonUtils;
import com.wx.spider.pc.feign.SqlWsClient;
import com.wx.spider.pc.repository.WxNewsListJsonRepository;
import com.wx.spider.pc.service.WxBizService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author:feng
 * @create:2021-04-25 18:33
 */
@Service
@Slf4j
public class WxBizServiceImpl implements WxBizService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private SqlWsClient sqlWsClient;

    @Autowired
    private WxNewsListJsonRepository wxNewsListJsonRepository;

    @Autowired
    public RocketMQTemplate rocketMQTemplate;

    @Override
    public void spiderBiz(Map<String, String> paramMap, WxBiz wxBiz) {

        String biz = wxBiz.getBiz();

        String phone = paramMap.get("phone");

        Integer pagecount = (wxBiz.getPagecount() == null || wxBiz.getPagecount() == 0) ? 1 : wxBiz.getPagecount();

        List<String> urlList = new ArrayList<>();

        int n = 0;
        int nextOffset = 0;
        pageFor:
        for (int i = 0; i < pagecount; i++) {
            if (i > 0) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (i != 0 && nextOffset == 0) {
                nextOffset = 10 * i;
            }
            StringBuffer sbf = new StringBuffer();
            sbf.append("https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=").append(paramMap.get("__biz").replace("######", "=="))
                    .append("&f=json&offset=" + nextOffset + "&count=10&is_ok=1&scene=&uin=").append(paramMap.get("uin")).append("&key=").append(paramMap.get("key"))
                    .append("&pass_ticket=").append(paramMap.get("pass_ticket"));

            String getLink = sbf.toString();

            WxBizSpider spider = new WxBizSpider();
            spider.setId(IdGenerateUtil.get().nextId());
            spider.setPhone(phone);
            spider.setOffset(nextOffset);
            spider.setAddtime(new Date());
            spider.setBizId(wxBiz.getId());
            spider.setUrl(getLink);
            try {
                sqlWsClient.saveWxBizSpider(spider);
            } catch (Exception e) {
                e.printStackTrace();
                log.info("fail save spider,biz:{},msg:{}", biz, e.getMessage());
            }

            String response = HttpClientUtil.getUrlResponse(sbf.toString(), "utf-8");

            //访问记录放入redis缓存
            String key = Constants.WX_BIZ_GET_LIST_ACCOUNT + phone;
            stringRedisTemplate.opsForList().rightPush(key, System.currentTimeMillis() + "");

            //存储到mongo
            WxNewsListJson wxNewsListJson = new WxNewsListJson();
            wxNewsListJson.setId(IdGenerateUtil.get().nextId());
            wxNewsListJson.setAddtime(System.currentTimeMillis());
            wxNewsListJson.setBiz(biz);
            wxNewsListJson.setOffset(nextOffset);
            wxNewsListJson.setPhone(phone);
            wxNewsListJson.setSpiderId(spider.getId());
            wxNewsListJson.setResJson(response);
            wxNewsListJsonRepository.save(wxNewsListJson);

            //获取下一页起始索引
            JSONObject jsonObject = null;
            try {
                jsonObject = JSON.parseObject(response);
                if (jsonObject != null) {
                    try {
                        Integer ret = jsonObject.getInteger("ret");
                        spider.setRet(ret);
                        try {
                            if (nextOffset == jsonObject.getInteger("next_offset")) {
                                System.out.println("到底了");
                                break;
                            } else {
                                nextOffset = jsonObject.getInteger("next_offset");
                            }
                            spider.setErrmsg(jsonObject.getString("errmsg"));
                            spider.setMsgCount(jsonObject.getInteger("msg_count"));
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.info("e3:fail get nextOffset!spiderId:{}", spider.getId());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.info("e2:fail get nextOffset!spiderId:{}", spider.getId());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.info("e1:fail get nextOffset!spiderId:{}", spider.getId());
            }

            Integer ifBreak = 0;

            //提取新闻
            if (jsonObject != null && jsonObject.getInteger("ret") == 0) {
                String tagStr = jsonObject.getString("general_msg_list");
                List<WxBizNews> newsList = JsonUtils.getNewFromJsonStr(tagStr);
                if (newsList == null || newsList.size() == 0) {
                    spider.setMsg("parse json error!");
                    try {
                        sqlWsClient.updateWxBizSpider(spider);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.info("1:fail update spider,biz:{},msg:{}", biz, e.getMessage());
                    }
                    continue;
                }

                for (WxBizNews wxBizNews : newsList) {
                    try {
                        wxBizNews.setSpiderId(spider.getId());
                        wxBizNews.setMedia(wxBiz.getName());
                        System.out.println(++n + "、" + wxBizNews.getTitle());

                        CommonResponse<Integer> res = sqlWsClient.getWxBizNewsCountByLink(wxBizNews.getContentUrl());
                        Integer count = res.getData();
                        if (count == null || !"0000".equals(res.getCode())) {
                            log.info("++++++++++++++++++++获取文章数量失败！++++++++++++++++++++++++");
                        } else if (count < 1) {
                            sqlWsClient.saveWxBizNews(wxBizNews);
                            System.out.println("save news success!");

                            //存入appmsg队列
                            urlList.add(wxBizNews.getContentUrl());

                            //发消息给java爬虫去提取内容
                            GetListMessage message = new GetListMessage(wxBizNews.getId(), spider.getId(), new Date());
                            Map<String, Object> header = new HashMap<>();
                            header.put("KEYS", wxBizNews.getId());
                            rocketMQTemplate.convertAndSend(MqMsgBean.PC_TO_JAVA.getTopic() + ":" + MqMsgBean.PC_TO_JAVA.getTag(), message, header);

                        } else {
                            System.out.println("文章已爬取");
                            ifBreak = 2;
                        }

                        //判断是否到了最晚时间
                        Date endtime = wxBiz.getEndtime();
                        if (endtime != null && wxBizNews.getPubtime() != null && wxBizNews.getPubtime().getTime() < endtime.getTime()) {
                            ifBreak = 1;
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        log.info(e.getMessage() + ":" + biz);
                    }
                }

            } else {
                spider.setMsg("error json");
                log.info("获取公众号文章失败：{}，页码：{}", wxBiz.getName(), i);
            }

            try {
                sqlWsClient.updateWxBizSpider(spider);
            } catch (Exception e) {
                e.printStackTrace();
                log.info("fail update spider,biz:{},msg:{}", biz, e.getMessage());
            }

            //判断是否跳出循环
            if(ifBreak == 2){
                log.info("已经到了该公众号的截止时间，停止爬虫！");
                break pageFor;
            }
            if(ifBreak == 1 && wxBiz.getIsRespider() != 1){
                log.info("之后的新闻已经入库，停止爬虫！");
                break pageFor;
            }
        }

        //存储待获取appmsg队列并发消息给mobile模块
        if (urlList.size() > 0) {
            //存储biz appmsg task
            String url = urlList.get(0);
            stringRedisTemplate.opsForList().rightPush(Constants.WX_BIZ_GET_APPMSG_QUNUE, url);
            //存储biz appmsg
            String bizKey = Constants.WX_BIZ_GET_APPMSG_BIZ + wxBiz.getBiz();
            stringRedisTemplate.opsForList().rightPushAll(bizKey, urlList);
            //通知空闲的模拟器去获取任务
            rocketMQTemplate.convertAndSend(MqMsgBean.PM_TO_MOBILE_SOCKET.getTopic(), "start tasks to free!");
        }


    }
}
